<html>
<script>
// When both timeouts finish, the counter will be 2.
window.completionCounter = 0;
function test()
{
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
    }

    // Get the iframe's window.
    var mainWindow = window;
    var iframeWindow = window.frames["testIframe"];

    // setTimeout with a callback specified as a JS closure.
    // This one should run in the context of the main page.
    iframeWindow.setTimeout(
        function() {
            document.getElementById("closureResult").innerText = (window == mainWindow ? "PASS" : "FAIL");
            completionCounter++;
        }, 0);

    // setTimeout with a JS string containing similar code.
    // This one should run 'inside' iframe.
    mainWindow.setTimeout.call(
        iframeWindow,
        "parent.document.getElementById('stringResult').innerText = (window != parent ? 'PASS' : 'FAIL');" +
        "parent.completionCounter++;",
        0);

    // The callback this value must be the context object.
    iframeWindow.setTimeout.call(window, function() {
        document.getElementById("contextResult").innerText = (this == mainWindow ? "PASS" : "FAIL");
        completionCounter++;
    }, 0);

    window.setInterval(checkResult, 10);
}
function checkResult() {
    if (completionCounter < 3)
        return;
    if (window.testRunner)
        testRunner.notifyDone();
}
</script>
<body onload="test()">
<p>Test verifies that a timeout callback is run in the proper execution context. 3 timeouts are set on a child iframe's window.  Test passes if you see 3 lines 'PASS' below.  See also:
<a href="https://html.spec.whatwg.org/multipage/webappapis.html#timer-initialisation-steps">https://html.spec.whatwg.org/multipage/webappapis.html#timer-initialisation-steps</a></p>

<div><span id="closureResult">FAIL: Test didn't run.</span> -- function argument: if the argument is a function, then the callback function must run in the relevant realm for that function object.</div>
<div><span id="stringResult">FAIL: Test didn't run.</span> -- string argument: if the argument is a string, then it must be compiled in the relevant realm for the context object, hence must run in the relevant realm for the context object.</div>
<div><span id="contextResult">FAIL: Test didn't run.</span> -- callback this value: the callback this value must be the context object.</div>
<iframe style="display:none" src="about:blank" name="testIframe"></iframe>
</body>
</html>
